﻿using System;
using System.ComponentModel;

namespace Pfz.DynamicObjects.CloneToModifyModel
{
	/// <summary>
	/// Base class used to implement ICtmObject.
	/// If you want to provide default implementations to some method(s) and still
	/// use the CloneToModifyGenerator you must inherit from this class.
	/// If you override the Equals method, the CloneToModifyGenerator will call it
	/// only after validating the right type of the object.
	/// </summary>
	public abstract class CtmObject:
		ICtmObject
	{
		private static NotSupportedException _Exception()
		{
			return new NotSupportedException("This method is implemented by calling the CloneToModifyGenerator.");
		}

		/// <summary>
		/// Gets the CtmType that describes information exclusive to
		/// Clone-to-Modify types.
		/// </summary>
		public virtual CtmType GetCtmType()
		{
			throw _Exception();
		}
	
		/// <summary>
		/// Gets a value indicating if this instance is read-only.
		/// </summary>
		public virtual bool GetIsReadOnly()
		{
			throw _Exception();
		}

		object ICtmObject.UntypedGetOldInstance()
		{
			throw _Exception();
		}

		object ICtmObject.UntypedAsReadOnly(bool keepOldInstance)
		{
			throw _Exception();
		}

		object ICtmObject.UntypedAsModifiable()
		{
			throw _Exception();
		}
		
		/// <summary>
		/// This method only exists because I don't know how to do a handler += in emitted code.
		/// In the future it should be removed.
		/// </summary>
		internal protected void AddPropertyChangedHandler(ref PropertyChangedEventHandler field, PropertyChangedEventHandler value)
		{
			field += value;
		}

		/// <summary>
		/// This method only exists because I don't know how to do a handler -= in emitted code.
		/// In the future it should be removed.
		/// </summary>
		internal protected void RemovePropertyChangedHandler(ref PropertyChangedEventHandler field, PropertyChangedEventHandler value)
		{
			field -= value;
		}
		
		/// <summary>
		/// Must be overriden if you create your own properties and want to copy
		/// their values to the clones.
		/// </summary>
		internal protected virtual void CopyValuesTo(CtmObject clone)
		{
		}
		
		/// <summary>
		/// Event invoked when the auto-generated properties of this class are changed.
		/// </summary>
		public virtual event PropertyChangedEventHandler PropertyChanged
		{
			add
			{
				throw _Exception();
			}
			remove
			{
				throw _Exception();
			}
		}
	}
}
